package com.ruoyi.system.controller;

import cn.hutool.core.util.IdUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.github.wxpay.sdk.WXPayUtil;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.OrderCodeUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.WeChatPayService;
import com.ruoyi.system.util.MdzwUtils;
import com.ruoyi.system.util.SHA1Util;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpStatus;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;

@RequestMapping("/system/pay")
@Validated
@RestController
@Api(tags = {"支付模块"})
@Slf4j
@Anonymous
public class PayController {

    @Autowired
    private MemberSetMenuMapper memberSetMenuMapper;
    @Autowired
    private WeChatPayService weChatPayService;
    /**
     * 微信支付应用ID
     */
    @Value("${pay.app_id}")
    private String appId;
    /**
     * 微信支付应用ID
     */
    @Value("${pay.api_key}")
    private String apiKey;

    /**
     * 微信支付商户号
     */
    @Value("${pay.mch_id}")
    private String mchId;

    @Value("${pay.secret}")
    private String appSecret;
    @Autowired
    private SysComboMealMapper sysComboMealMapper;
    @Autowired
    private SysBillDetailsMapper sysBillDetailsMapper;
    @Autowired
    private SysMemberMapper sysMemberMapper;
    @Autowired
    private SysUserMapper sysUserMapper;

    /**
     * 准备微信支付订单
     * 接收前端传来的请求参数，验证订单和用户信息，调用微信支付统一下单API准备支付
     *
     * @param request 包含订单和用户信息的请求体，包括订单编号(orderCode)等
     * @return 如果订单验证成功，返回包含微信支付所需参数的AjaxResult对象；否则返回错误信息
     */
    @PostMapping("/wechatPay")
    public AjaxResult preparePayment(@RequestBody Map request) {
        Map<String, Object> resultMap = new HashMap<String, Object>();
        try {
            // 获取会员套餐配置
            List<SysComboMeal> sysComboMeals = sysComboMealMapper.selectSysComboMealList(new SysComboMeal());
            if (sysComboMeals.isEmpty()) {
                return AjaxResult.error("套餐配置不存在");
            }
            SysComboMeal sysComboMeal = sysComboMeals.get(0);

            WeChatPay weChatPay = new WeChatPay();
            //公众号appid
            weChatPay.setAppid(appId)
                    // 商户号
                    .setMch_id(mchId)
                    //api密钥
                    .setApi_key(apiKey)
                    // 32位随机字符串
                    .setNonce_str(WXPayUtil.generateNonceStr())
                    // 商品描述
                    .setBody(sysComboMeal.getComboMealName())
                    //标价金额
                    .setTotal_fee(sysComboMeal.getComboMealAmount())
                    // 商户订单号 唯一
                    .setOut_trade_no(IdUtil.simpleUUID())
                    // 终端IP
                    .setSpbill_create_ip("120.27.133.245")
                    //异步回调地址
                    .setNotify_url("https://h5.tonghuajiankang.com/prod-api/system/pay/weChatPayCallback")
                    // 交易类型 JSAPI--JSAPI支付（或小程序支付）、NATIVE--Native支付、APP--app支付，MWEB--H5支付
                    .setTrade_type("JSAPI")
//                    .setOpenid("o0Icv6tEb5R_-rM9QVohK4_h55sI")
                    .setOpenid(request.get("openid").toString())
                    //.setSub_mch_id("1609469848")//子商户号 微信支付 分配的子商户号（服务商模式的时候填入）
                    //附加数据，在查询API和支付通知中原样返回，该字段主要用于商户携带订单的自定义数据
                    .setAttach(OrderCodeUtils.getOrderCode("V"));
            resultMap = weChatPayService.unifiedorder(weChatPay);
            if (resultMap.get("code").equals(0)) {
                log.info("微信支付预下单成功，获取登录人信息, outTradeNo: {}", JSON.toJSON(request).toString());
                // 微信预下单成功后，添加会员套餐订单
                MemberSetMenu memberSetMenu = new MemberSetMenu();
                if (ObjectUtils.isNotEmpty(request.get("memberId"))) {
                    memberSetMenu.setMemberId(request.get("memberId").toString());
                }
                Date now = new Date();
                memberSetMenu.setPayTime(now);
                memberSetMenu.setWxCode(weChatPay.getNonce_str());
                memberSetMenu.setOrderCode(weChatPay.getAttach());
                memberSetMenu.setOrderMoney(weChatPay.getTotal_fee());
                memberSetMenu.setOrderStatus("1");
                memberSetMenu.setCreateTime(now);
                memberSetMenu.setUpdateTime(now);
                // 此处添加会员套餐订单逻辑
                memberSetMenuMapper.insertMemberSetMenu(memberSetMenu);
            }
            log.info("返回结果：{}", JSONUtil.toJsonStr(resultMap));
        } catch (Exception e) {
            resultMap.put("code", 2);
            resultMap.put("msg", "系统异常错误代码：" + e.getMessage());
            e.printStackTrace();
        }
        return AjaxResult.success(resultMap);
    }

//    @GetMapping(value = "/resCode")
//    public void  resCode(HttpServletRequest request, HttpSession session, HttpServletResponse response) throws IOException {
//        //获取回调地址中的code
//        String code = request.getParameter("code");
//        //拼接url,appId是指公众号的id,secret指的是公众号的
//        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="+appId+"&secret="+secret+"&code=" + code + "&grant_type=authorization_code";
//        JSONObject jsonObject = doGetJson(url);
//        //1.获取微信用户的openid
//        String openId = jsonObject.getString("openid");
//        session.setAttribute("openId",openId);
//    }

    /**
     * 通过code换取网页授权access_token
     * 该接口使用code换取微信网页授权的access_token，并进一步获取用户信息。
     *
     * @param code 用户的授权code，用于换取access_token
     * @return 包含用户信息的AjaxResult对象
     */
    @GetMapping("/getAccessToken")
    public AjaxResult getAccessToken(@RequestParam String code) {
        try {
            String accessUrl = String.format("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code", appId, appSecret, code);

            String accessJsonStr = HttpUtil.get(accessUrl);
            if (StringUtils.isEmpty(accessJsonStr)) {
                log.warn("Get access token failed, empty response from wechat");
                return AjaxResult.error("获取access_token失败");
            }

            Map<String, String> accessMap = JSONUtil.toBean(accessJsonStr, Map.class);
            String accessToken = accessMap.get("access_token");
            String openId = accessMap.get("openid");

            if (StringUtils.isEmpty(accessToken) || StringUtils.isEmpty(openId)) {
                log.warn("Get access token failed, accessToken or openId is empty");
                return AjaxResult.error("access_token或openid为空");
            }
            String userUrl = String.format("https://api.weixin.qq.com/sns/userinfo?access_token=%s&openid=%s&lang=zh_CN", accessToken, openId);
            String userInfo = HttpUtil.get(userUrl);
            JSONObject jsonObject = JSONObject.parseObject(userInfo);
            SysUser user = new SysUser();
            user.setOpenId(openId);
            List<SysUser> sysUsers = sysUserMapper.selectUserList(user);
            Date now = new Date();
            if (ObjectUtils.isEmpty(sysUsers)) {
                SysUser sysUser = new SysUser();
                sysUser.setOpenId(openId);
                sysUser.setUserName(jsonObject.getString("nickname"));
                sysUser.setNickName(jsonObject.getString("nickname"));
                sysUser.setAvatar(jsonObject.getString("headimgurl"));
                sysUser.setSex(jsonObject.getInteger("sex").toString());
                sysUserMapper.insertUser(sysUser);
                SysMember sysMember = new SysMember();
                sysMember.setMemberName(jsonObject.getString("nickname"));
                sysMember.setMemberPicture(jsonObject.getString("headimgurl"));
                sysMember.setCumulativeMoney("0.00");
                sysMember.setAccountBalance("0.00");
                sysMember.setMemberSex(jsonObject.getInteger("sex").toString());
                sysMember.setCreateTime(now);
                sysMember.setUpdateTime(now);
                sysMember.setMemberLevel("0");
                sysMember.setOpenId(openId);
                sysMemberMapper.insertSysMember(sysMember);
            }
            log.info("获取用户信息：{}", userInfo);
            if (StringUtils.isEmpty(userInfo)) {
                log.warn("Get user info failed, empty response from wechat");
                return AjaxResult.error("获取用户信息失败");
            }

            return AjaxResult.success(JSONUtil.toBean(userInfo, Map.class));
        } catch (Exception e) {
            log.error("Wechat auth failed: {}", e.getMessage());
            return AjaxResult.error("微信授权失败: " + e.getMessage());
        }
    }

    /**
     * 微信支付异步回调通知处理接口
     * 该接口用于处理微信支付成功的异步回调通知，验证签名并响应处理结果。
     *
     * @param request  HTTP请求，包含微信支付回调的所有数据
     * @param response HTTP响应，用于返回处理结果
     */
    @PostMapping(value = "/weChatPayCallback")
    public void weChatPayCallback(HttpServletRequest request, HttpServletResponse response) {
        try (PrintWriter out = response.getWriter()) {
            Map<String, Object> resultMap = weChatPayService.weChatPayCallback(request, apiKey);
            if ("YES".equals(resultMap.get("Verify"))) {
                log.info("验签成功");
                out.write(String.valueOf(resultMap.get("returnWeChat")));
                Map<String, String> wxResultMapData = (Map<String, String>) resultMap.get("data");
                String attach = wxResultMapData.get("attach");
                MemberSetMenu param = new MemberSetMenu();
                param.setOrderCode(attach);
                List<MemberSetMenu> memberSetMenus = memberSetMenuMapper.selectMemberSetMenuList(param);
                if (!memberSetMenus.isEmpty()) {
                    // 更新订单状态为已支付
                    MemberSetMenu memberSetMenu = memberSetMenus.get(0);
                    memberSetMenu.setUpdateTime(new Date());
                    memberSetMenu.setOrderStatus("2");
                    memberSetMenuMapper.updateMemberSetMenu(memberSetMenu);

                    // 添加用户金额、账单明细
                    if (ObjectUtils.isNotEmpty(memberSetMenu.getMemberId())) {
                        List<SysComboMeal> sysComboMeals = sysComboMealMapper.selectSysComboMealList(new SysComboMeal());
                        SysComboMeal sysComboMeal = sysComboMeals.get(0);
                        BigDecimal multiply = new BigDecimal(1);
                        BigDecimal accountBalance = new BigDecimal("0.00");
                        if (ObjectUtils.isNotEmpty(sysComboMeal.getMemberInvite())){
                            multiply = new BigDecimal(sysComboMeal.getMemberInvite()).multiply(BigDecimal.valueOf(0.01));

                        }
                        SysBillDetails sysBillDetail = new SysBillDetails();
                        sysBillDetail.setMatterType("套餐返现");
                        SysMember sysMember = sysMemberMapper.selectSysMemberById(memberSetMenu.getMemberId());
                        Date now = new Date();
                        if (ObjectUtils.isNotEmpty(sysComboMeal)) {
                            // 记录用户余额变动金额，并更新用户余额和会员等级等信息
                            String money = "0.00";
                            if (ObjectUtils.isNotEmpty(sysMember)) {
                                money = sysMember.getAccountBalance();
                            }
                            accountBalance = new BigDecimal(sysComboMeal.getBackMoney()).add(new BigDecimal(sysComboMeal.getComboMealAmount())).add(new BigDecimal(money));
                            sysMember.setAccountBalance(accountBalance.toString());
                            sysMember.setMemberLevel(sysComboMeal.getMemberLevel());
                            sysMember.setMemberBeginDate(now);
                            // 计算会员过期时间
                            // 获取当前日期
                            LocalDate today = LocalDate.now();
                            // 组合明天的日期和00:00时间
                            LocalDateTime dayAfterTomorrowMidnight = LocalDateTime.of(today.plusDays(Integer.parseInt(sysComboMeals.get(0).getMemberDay()) + 1), LocalTime.MIDNIGHT);
                            Date endTime = Date.from(dayAfterTomorrowMidnight.atZone(ZoneId.systemDefault()).toInstant());
//                            Calendar calendar = Calendar.getInstance();
//                            calendar.setTime(now);
//                            calendar.add(Calendar.DATE, (Integer.parseInt(sysComboMeals.get(0).getMemberDay()) + 1));
//                            Date endTime = calendar.getTime();
                            sysMember.setMemberEndDate(endTime);
                            sysBillDetail.setAccountBalance(sysComboMeal.getBackMoney());
                            sysMemberMapper.updateSysMember(sysMember);
                        } else {
                            sysBillDetail.setAccountBalance(memberSetMenu.getOrderMoney());
                        }
                        // 首次余额变动为充值，后续变动为消费
                        sysBillDetail.setMemberId(memberSetMenu.getMemberId());
                        sysBillDetail.setCreateTime(now);
                        sysBillDetail.setUpdateTime(now);
                        sysBillDetailsMapper.insertSysBillDetails(sysBillDetail);
                        SysBillDetails sysBillDetail1 = new SysBillDetails();
                        sysBillDetail1.setMemberId(memberSetMenu.getMemberId());
                        sysBillDetail1.setMatterType("会员办理");
                        sysBillDetail1.setAccountBalance(memberSetMenu.getOrderMoney());
                        sysBillDetail1.setCreateTime(now);
                        sysBillDetail1.setUpdateTime(now);
                        sysBillDetailsMapper.insertSysBillDetails(sysBillDetail1);
                        if (ObjectUtils.isNotEmpty(sysMember.getInviteBy()) && ObjectUtils.isNotEmpty(sysComboMeal.getInviteStatus()) && ObjectUtils.isNotEmpty(sysMember.getInviteBy())) {
                            String money = accountBalance.multiply(multiply).toString();
                            // 获取邀请人信息，并更新其余额和账单明细
                            SysMember sysMember1 = sysMemberMapper.selectSysMemberById(sysMember.getInviteBy());
                            // 更新邀请人余额和账单明细
                            sysMember1.setAccountBalance(new BigDecimal(sysMember1.getAccountBalance()).add(new BigDecimal(money)).toString());
                            sysMemberMapper.updateSysMember(sysMember1);
                            SysBillDetails shareSysBillDetail = new SysBillDetails();
                            shareSysBillDetail.setAccountBalance(money);
                            shareSysBillDetail.setMatterType("好友邀请");
                            shareSysBillDetail.setMemberId(sysMember.getInviteBy());
                            shareSysBillDetail.setCreateTime(now);
                            shareSysBillDetail.setUpdateTime(now);
                            sysBillDetailsMapper.insertSysBillDetails(shareSysBillDetail);
                        }
                    }

                }
                log.info("收到微信回调：{}", JSONUtil.toJsonStr(wxResultMapData));
            } else if ("NO".equals(resultMap.get("Verify"))) {
                log.warn("验签失败");
                response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            }
        } catch (Exception e) {
            log.error("微信支付回调处理异常", e);
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
        }
    }

    /**
     * 查询支付状态接口
     * 根据商户订单号查询支付状态，返回支付结果信息。
     *
     * @param outNo 商户订单号，用于查询支付状态的唯一标识
     * @return 返回包含支付状态信息的Map对象，其中包含code和msg等字段
     */
    @GetMapping(value = "/queryPayStatus")
    public Map<String, Object> queryPayStatus(@RequestParam String outNo) {
        Map<String, Object> resultMap = new HashMap<>(4);
        if (StringUtils.isEmpty(outNo)) {
            resultMap.put("code", 400);
            resultMap.put("msg", "商户订单号不能为空");
            return resultMap;
        }

        try {
            WeChatPay weChatPay = new WeChatPay();
            weChatPay.setAppid(appId).setMch_id(mchId).setApi_key(apiKey).setNonce_str(WXPayUtil.generateNonceStr()).setOut_trade_no(outNo);
            return WeChatPayService.queryPayStatus(weChatPay);
        } catch (IllegalArgumentException e) {
            resultMap.put("code", 400);
            resultMap.put("msg", "参数错误: " + e.getMessage());
            log.error("查询支付状态参数错误, outNo: {}", outNo, e);
        } catch (Exception e) {
            resultMap.put("code", 500);
            resultMap.put("msg", "系统异常");
            log.error("查询支付状态系统异常, outNo: {}", outNo, e);
        }
        return resultMap;
    }

    /**
     * 获取微信访问令牌
     * 通过微信的appid和secret获取访问令牌(access_token)
     *
     * @return 返回获取到的微信访问令牌(access_token)
     * @throws RuntimeException 如果请求失败、响应无效或获取令牌过程中发生异常，则抛出RuntimeException异常
     */
    @GetMapping(value = "/getToken")
    public String getToken() {
        // 构建获取微信访问令牌的URL
        String url = "https://api.weixin.qq.com/cgi-bin/token?" + "grant_type=client_credential" + "&appid=" + appId + "&secret=" + appSecret;

        // 使用默认配置创建HttpClient实例
        try (CloseableHttpClient client = HttpClients.createDefault()) {
            // 创建HttpGet请求
            HttpGet get = new HttpGet(url);
            // 执行请求并获取响应
            try (CloseableHttpResponse response = client.execute(get)) {
                // 检查响应状态码是否为200 OK
                if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                    // 如果响应状态码不是200，抛出RuntimeException异常
                    throw new RuntimeException("Request failed: " + response.getStatusLine());
                }

                // 获取响应实体
                HttpEntity entity = response.getEntity();
                // 将响应实体转换为字符串
                String content = EntityUtils.toString(entity);
                // 将响应字符串解析为JSON对象
                JSONObject res = JSONObject.parseObject(content);

                // 检查JSON对象是否为空或是否包含access_token键
                if (res == null || !res.containsKey("access_token")) {
                    // 如果JSON对象为空或不包含access_token键，抛出RuntimeException异常
                    throw new RuntimeException("Invalid response: " + content);
                }

                // 返回access_token的值
                return res.getString("access_token");
            }
        } catch (Exception e) {
            // 如果在获取访问令牌的过程中发生异常，抛出RuntimeException异常
            throw new RuntimeException("Failed to get access token", e);
        }
    }


    /**
     * 获取JsApi票据
     * 通过传入的accessToken向微信服务器请求JsApi票据
     *
     * @param accessToken 访问令牌，用于向微信服务器请求数据
     * @return 成功时返回JsApi票据，失败时抛出异常
     * @throws IllegalStateException    如果请求失败或未获取到票据
     * @throws IllegalArgumentException 如果参数无效
     */
    @GetMapping(value = "/getTicket")
    @ResponseBody
    public AjaxResult getJsApiTicket(@RequestParam String accessToken) throws UnsupportedEncodingException {

        if (StringUtils.isEmpty(accessToken)) {
            throw new IllegalArgumentException("accessToken cannot be empty");
        }

        String url = String.format("https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi", URLEncoder.encode(accessToken, String.valueOf(StandardCharsets.UTF_8)));

        try (CloseableHttpClient client = HttpClientBuilder.create().build()) {
            HttpGet get = new HttpGet(url);
            try (CloseableHttpResponse response = client.execute(get)) {
                if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
                    throw new IllegalStateException("HTTP request failed with code: " + response.getStatusLine().getStatusCode());
                }

                HttpEntity result = response.getEntity();
                String content = EntityUtils.toString(result, StandardCharsets.UTF_8);
                JSONObject res = JSONObject.parseObject(content);
                if (res == null) {
                    throw new IllegalStateException("Invalid response content");
                }

                Map<String, Object> map = MdzwUtils.parseJsonToMap(res);
                if (!map.containsKey("ticket")) {
                    throw new IllegalStateException("Failed to get ticket from response");
                }

                Map<String, Object> paramMap = new HashMap<>();
                paramMap.put("url", url);
                paramMap.put("noncestr", generateRandomString());
                paramMap.put("jsapi_ticket", map.get("ticket").toString());
                paramMap.put("timestamp", System.currentTimeMillis() / 1000);
                paramMap.put("signature", SHA1Util.sha1(formatUrlMap(paramMap, false, false)));
                String requestParam = formatUrlMap(paramMap, false, false);
                return AjaxResult.success(paramMap);
//                return SHA1Util.sha1(requestParam);
            }
        } catch (Exception e) {
            throw new IllegalStateException("Error getting jsapi ticket", e);
        }
    }


    /**
     * 获取16位随机字符串（包含大小写字母和数字）
     *
     * @return 返回生成的16位随机字符串
     */
    public String generateRandomString() {
        // 定义字符集，包括大小写字母和数字
        final String CHARACTERS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        // 定义字符串长度
        final int LENGTH = 16;
        // 获取当前线程的随机数生成器
        final ThreadLocalRandom random = ThreadLocalRandom.current();

        // 创建一个StringBuilder对象，初始容量为16
        StringBuilder sb = new StringBuilder(LENGTH);
        // 循环16次，生成16个字符的字符串
        for (int i = 0; i < LENGTH; i++) {
            // 从字符集中随机选择一个字符并追加到StringBuilder对象中
            sb.append(CHARACTERS.charAt(random.nextInt(CHARACTERS.length())));
        }
        // 将StringBuilder对象转换为字符串并返回
        return sb.toString();
    }


    /**
     * 将参数按照字段名排序并生成URL格式的字符串
     *
     * @param paraMap    待格式化的参数集合
     * @param urlEncode  是否对值进行URL编码
     * @param keyToLower 是否将键转换为小写
     * @return 格式化后的URL字符串，如果参数为空或发生异常则返回null
     */
    public static String formatUrlMap(Map<String, Object> paraMap, boolean urlEncode, boolean keyToLower) {
        // 判断参数集合是否为空
        if (paraMap == null || paraMap.isEmpty()) {
            return null;
        }
        try {
            // 将参数集合转换为List并排序
            List<Map.Entry<String, Object>> infoIds = new ArrayList<>(paraMap.entrySet());
            Collections.sort(infoIds, Comparator.comparing(Map.Entry::getKey));

            // 初始化StringBuilder对象
            StringBuilder buf = new StringBuilder();

            // 遍历排序后的参数集合
            for (Map.Entry<String, Object> item : infoIds) {
                // 判断键是否为空
                if (StringUtils.isNotBlank(item.getKey())) {
                    // 根据需求将键转换为小写
                    String key = keyToLower ? item.getKey().toLowerCase() : item.getKey();
                    Object val = item.getValue();
                    String valueStr = val != null ? val.toString() : "";

                    // 判断是否对值进行URL编码
                    if (urlEncode) {
                        valueStr = URLEncoder.encode(valueStr, StandardCharsets.UTF_8.name());
                    }

                    // 拼接键和值，并在末尾加上"&"
                    buf.append(key).append("=").append(valueStr).append("&");
                }
            }
            // 去掉末尾的"&"
            String result = buf.toString();
            return result.isEmpty() ? result : result.substring(0, result.length() - 1);
        } catch (UnsupportedEncodingException e) {
            // 捕获编码异常，返回null
            return null;
        }
    }

}
